package com.online_exam.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.online_exam.domain.*;
import com.online_exam.domain.enums.ExamPaperAnswerStatusEnum;
import com.online_exam.domain.enums.ExamPaperTypeEnum;
import com.online_exam.domain.enums.QuestionTypeEnum;
import com.online_exam.domain.exam.ExamPaperTitleItemObject;
import com.online_exam.repository.ExamAnswerMapper;
import com.online_exam.repository.ExamMapper;
import com.online_exam.repository.QuestionAnswerMapper;
import com.online_exam.repository.QuestionMapper;
import com.online_exam.service.ExamAnswerService;
import com.online_exam.service.QuestionAnswerService;
import com.online_exam.service.TextContentService;
import com.online_exam.service.UserService;
import com.online_exam.viewmodel.student.exampaper.ExamPaperAnswerPageVM;
import com.online_exam.viewmodel.student.exampaper.ExamPaperSubmitItemVM;
import com.online_exam.viewmodel.student.exampaper.ExamPaperSubmitVM;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ExamAnswerServiceImpl implements ExamAnswerService {

    @Autowired
    ExamAnswerMapper examAnswerMapper;
    @Autowired
    QuestionMapper questionMapper;
    @Autowired
    ExamMapper examMapper;
    @Autowired
    TextContentService textContentService;
    @Autowired
    QuestionAnswerService questionAnswerService;




    @Override
    public int insert(ExamPaperAnswer examPaperAnswer) {
        return examAnswerMapper.insert(examPaperAnswer);
    }


    @Override
    public void examPaperAnswerFromVM(ExamPaperSubmitVM examPaperSubmitVM,User user) {
        ExamPaperAnswerInfo examPaperAnswerInfo = new ExamPaperAnswerInfo();
        Date now = new Date();
        ExamPaper examPaper = examMapper.selectById(examPaperSubmitVM.getId());
        ExamPaperTypeEnum paperTypeEnum = ExamPaperTypeEnum.fromCode(examPaper.getPaperType());
        //任务试卷只能做一次
        /*if (paperTypeEnum == ExamPaperTypeEnum.Task) {
            ExamPaperAnswer examPaperAnswer = examAnswerMapper.getByPidUid(examPaperSubmitVM.getId(), user.getId());
            if (null != examPaperAnswer)
                return null;
        }*/
        String frameTextContent = textContentService.selectById(examPaper.getFrameTextContentId()).getContent();
        List<ExamPaperTitleItemObject> examPaperTitleItemObjects = JSON.parseArray(frameTextContent, ExamPaperTitleItemObject.class);
        List<Integer> questionIds = examPaperTitleItemObjects.stream().flatMap(t -> t.getQuestionItems().stream().map(q -> q.getId())).collect(Collectors.toList());
        List<Question> questions = questionMapper.selectByIds(questionIds);
        //将题目结构的转化为题目答案 -根据原试卷题目id，转原题目为对应的已作答题目（原题目+作答内容）
        List<ExamPaperQuestionCustomerAnswer> examPaperQuestionCustomerAnswers = examPaperTitleItemObjects.stream()
                //大题中的小题
                .flatMap(t -> t.getQuestionItems().stream()
                        //操作小题实体
                        .map(q -> {
                            //获取对应的原题内容
                            Question question = questions.stream().filter(tq -> tq.getId().equals(q.getId())).findFirst().get();
                            //获取小题对应的答题VM
                            ExamPaperSubmitItemVM customerQuestionAnswer = examPaperSubmitVM.getAnswerItems().stream()
                                    .filter(tq -> tq.getQuestionId().equals(q.getId()))
                                    .findFirst()
                                    .orElse(null);
                            //生成一个答题实体 -根据答题VM和原题
                            ExamPaperQuestionCustomerAnswer questionAnswer = QuestionAnswerFromVM(question, customerQuestionAnswer, examPaper, q.getItemOrder(), user, now);
                            return questionAnswer;
                        })
                ).collect(Collectors.toList());

        //生成已作答试卷
        ExamPaperAnswer examPaperAnswer = ExamAnswerFromVM(examPaperSubmitVM, examPaper, examPaperQuestionCustomerAnswers, user, now);
        //插入答卷并获取id
        examAnswerMapper.insert(examPaperAnswer);
        Integer examPaperAnswerId = examPaperAnswer.getId();
        //根据答卷ID插入答题
        examPaperQuestionCustomerAnswers.stream().forEach(q->{
            q.setExamPaperAnswerId(examPaperAnswerId);
            questionAnswerService.insert(q);
        });
    }

    @Override
    public ExamPaperAnswer selectById(Integer id) {
        return examAnswerMapper.select(id);
    }

    @Override
    public PageInfo<ExamPaperAnswer> studentPage(ExamPaperAnswerPageVM model) {
        return PageHelper.startPage(model.getPageIndex(),model.getPageSize()).doSelectPageInfo(()->examAnswerMapper.page(model));
    }


    private ExamPaperAnswer ExamAnswerFromVM(ExamPaperSubmitVM examPaperSubmitVM, ExamPaper examPaper, List<ExamPaperQuestionCustomerAnswer> examPaperQuestionCustomerAnswers, User user, Date now) {
        Integer systemScore = examPaperQuestionCustomerAnswers.stream().mapToInt(a -> a.getCustomerScore()).sum();
        long questionCorrect = examPaperQuestionCustomerAnswers.stream().filter(a -> a.getCustomerScore().equals(a.getQuestionScore())).count();
        ExamPaperAnswer examPaperAnswer = new ExamPaperAnswer();
        examPaperAnswer.setPaperName(examPaper.getName());
        examPaperAnswer.setDoTime(examPaperSubmitVM.getDoTime());
        examPaperAnswer.setExamPaperId(examPaper.getId());
        examPaperAnswer.setCreateUser(user.getId());
        examPaperAnswer.setCreateTime(now);
        examPaperAnswer.setSubjectId(examPaper.getSubjectId());
        examPaperAnswer.setQuestionCount(examPaper.getQuestionCount());
        examPaperAnswer.setPaperScore(examPaper.getScore());
        examPaperAnswer.setPaperType(examPaper.getPaperType());
        examPaperAnswer.setSystemScore(systemScore);
        examPaperAnswer.setUserScore(systemScore);
        examPaperAnswer.setTaskExamId(examPaper.getTaskExamId());
        examPaperAnswer.setQuestionCorrect((int) questionCorrect);
        //判断是否需要评分，遇到填空或简答，则返回ture，anyMatch检测到一个true就返回ture
        boolean needJudge = examPaperQuestionCustomerAnswers.stream().anyMatch(d -> QuestionTypeEnum.needSaveTextContent(d.getQuestionType()));
        if (needJudge) {
            examPaperAnswer.setStatus(ExamPaperAnswerStatusEnum.WaitJudge.getCode());
        } else {
            examPaperAnswer.setStatus(ExamPaperAnswerStatusEnum.Complete.getCode());
        }
        return examPaperAnswer;
    }

    private ExamPaperQuestionCustomerAnswer QuestionAnswerFromVM(Question question, ExamPaperSubmitItemVM customerQuestionAnswer, ExamPaper examPaper, Integer itemOrder, User user, Date now) {
        ExamPaperQuestionCustomerAnswer examPaperQuestionCustomerAnswer = new ExamPaperQuestionCustomerAnswer();
        examPaperQuestionCustomerAnswer.setQuestionId(question.getId());
        examPaperQuestionCustomerAnswer.setExamPaperId(examPaper.getId());
        examPaperQuestionCustomerAnswer.setQuestionScore(question.getScore());
        examPaperQuestionCustomerAnswer.setSubjectId(examPaper.getSubjectId());
        examPaperQuestionCustomerAnswer.setItemOrder(itemOrder);
        examPaperQuestionCustomerAnswer.setCreateTime(now);
        examPaperQuestionCustomerAnswer.setCreateUser(user.getId());
        examPaperQuestionCustomerAnswer.setQuestionType(question.getQuestionType());
        examPaperQuestionCustomerAnswer.setQuestionTextContentId(question.getInfoTextContentId());
        if (null == customerQuestionAnswer) {
            examPaperQuestionCustomerAnswer.setCustomerScore(0);
        } else {
            setSpecialFromVM(examPaperQuestionCustomerAnswer, question, customerQuestionAnswer);
        }
        return examPaperQuestionCustomerAnswer;
    }

    private void setSpecialFromVM(ExamPaperQuestionCustomerAnswer examPaperQuestionCustomerAnswer, Question question, ExamPaperSubmitItemVM customerQuestionAnswer) {
        QuestionTypeEnum questionTypeEnum = QuestionTypeEnum.fromCode(examPaperQuestionCustomerAnswer.getQuestionType());
        switch (questionTypeEnum) {
            case SingleChoice:
            case TrueFalse:
                examPaperQuestionCustomerAnswer.setAnswer(customerQuestionAnswer.getContent());
                examPaperQuestionCustomerAnswer.setDoRight(question.getCorrect().equals(customerQuestionAnswer.getContent()));
                examPaperQuestionCustomerAnswer.setCustomerScore(examPaperQuestionCustomerAnswer.getDoRight() ? question.getScore() : 0);
                break;
            case MultipleChoice:
                String customerAnswer = JSON.toJSONString(customerQuestionAnswer.getContentArray());
                examPaperQuestionCustomerAnswer.setAnswer(customerAnswer);
                examPaperQuestionCustomerAnswer.setDoRight(customerAnswer.equals(question.getCorrect()));
                examPaperQuestionCustomerAnswer.setCustomerScore(examPaperQuestionCustomerAnswer.getDoRight() ? question.getScore() : 0);
                break;
            case GapFilling:
                String correctAnswer = JSON.toJSONString(customerQuestionAnswer.getContentArray());
                examPaperQuestionCustomerAnswer.setAnswer(correctAnswer);
                examPaperQuestionCustomerAnswer.setCustomerScore(0);
                break;
            default:
                examPaperQuestionCustomerAnswer.setAnswer(customerQuestionAnswer.getContent());
                examPaperQuestionCustomerAnswer.setCustomerScore(0);
                break;
        }
    }

    @Override
    public ExamPaperSubmitVM examPaperAnswerToVM(Integer id) {
        ExamPaperSubmitVM examPaperSubmitVM = new ExamPaperSubmitVM();
        ExamPaperAnswer examPaperAnswer = examAnswerMapper.select(id);
        examPaperSubmitVM.setId(examPaperAnswer.getId());
        examPaperSubmitVM.setDoTime(examPaperAnswer.getDoTime());
        examPaperSubmitVM.setScore(examPaperAnswer.getUserScore().toString());
        //根据试卷id找出所有答题
        List<ExamPaperQuestionCustomerAnswer> questionAnswers = questionAnswerService.selectListByPaperAnswerId(id);
        //把答题转成VM
        List<ExamPaperSubmitItemVM> examPaperSubmitItemVMS = questionAnswers.stream()
                .map(a -> questionAnswerService.questionAnswersToVM(a))
                .collect(Collectors.toList());
        //设置答题列表到答卷
        examPaperSubmitVM.setAnswerItems(examPaperSubmitItemVMS);
        return examPaperSubmitVM;
    }
}

